<html>
<head><meta charset="utf-8"><title>Cow layout stability · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html">Cow layout stability</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="190592350"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190592350" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Shnatsel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190592350">(Mar 14 2020 at 11:08)</a>:</h4>
<p>Has the layout of <code>std::borrow::Cow</code> been specified/stabilized yet?<br>
I'm asking because somebody has found a way to implement it in a slightly more compact way (3 words instead of 4) and I'm wondering if a similar approach could be taken by <code>std</code> eventually: <a href="https://github.com/maciejhirsz/beef/" target="_blank" title="https://github.com/maciejhirsz/beef/">https://github.com/maciejhirsz/beef/</a></p>



<a name="190592424"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190592424" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190592424">(Mar 14 2020 at 11:10)</a>:</h4>
<p><code>beef</code> only works for things that have a capacity field, while <code>std::borrow::Cow</code> works for all values.</p>



<a name="190592553"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190592553" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> HeroicKatora <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190592553">(Mar 14 2020 at 11:15)</a>:</h4>
<p>It also doesn't differentiate between <code>String::new()</code> and a borrowed string, if I interpret the code correctly. That is mostly inconsequential for strings and vectors but still a slight detail.</p>



<a name="190595716"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190595716" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190595716">(Mar 14 2020 at 12:30)</a>:</h4>
<p>(But regardless, Cow's layout is definitely not stable to my knowledge -- it's just a regular repr(Rust) enum, right?)</p>



<a name="190717556"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190717556" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190717556">(Mar 16 2020 at 12:54)</a>:</h4>
<p>if String's implementation will ever change to allocate on <code>String::new()</code> or "break their layout" <code>beef</code> will break..</p>



<a name="190718134"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190718134" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190718134">(Mar 16 2020 at 12:59)</a>:</h4>
<p><code>beef</code> doesn't transmute a <code>String</code>. Instead it uses <code>.as_mut_ptr()</code>, <code>.len()</code> and <code>.capacity()</code> to deconstruct the string and later uses <code>Vec::from_raw_parts</code> + <code>String::from_utf8_unchecked</code> to reconstruct it: <a href="https://github.com/maciejhirsz/beef/blob/64b7812a3e10524a64404a47551e59a1a4b0f195/src/lib.rs#L86-L90" target="_blank" title="https://github.com/maciejhirsz/beef/blob/64b7812a3e10524a64404a47551e59a1a4b0f195/src/lib.rs#L86-L90">https://github.com/maciejhirsz/beef/blob/64b7812a3e10524a64404a47551e59a1a4b0f195/src/lib.rs#L86-L90</a></p>



<a name="190721075"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190721075" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190721075">(Mar 16 2020 at 13:25)</a>:</h4>
<p>you're right. my mistake, they don't care about the layout of string.</p>
<p>But can't we somehow enable the niche optimization we have for option on Cow too? because <code>size_of::&lt;Option&lt;String&gt;&gt;() == size_of::&lt;String&gt;()</code> so we could theoretically use that same bit for Cow for the discriminant</p>



<a name="190838454"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190838454" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190838454">(Mar 17 2020 at 12:14)</a>:</h4>
<p>there's no bit though. there's a single "niche value", 0x0000000000000000</p>



<a name="190838482"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190838482" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190838482">(Mar 17 2020 at 12:14)</a>:</h4>
<p>that's enough for <code>None</code> but not enough for <code>Borrowed(ptr)</code>, because the latter has data to store</p>



<a name="190840130"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190840130" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190840130">(Mar 17 2020 at 12:31)</a>:</h4>
<p>For <code>Cow&lt;str&gt;</code> <code>Owned</code> could be represented as "ptr | len | capacity" while <code>Borrowed</code> could be represented as "0x0 | ptr | len".</p>



<a name="190964144"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964144" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964144">(Mar 18 2020 at 10:53)</a>:</h4>
<p><span class="user-mention" data-user-id="119009">@eddyb</span> can we do this? ^</p>



<a name="190964174"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964174" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964174">(Mar 18 2020 at 10:53)</a>:</h4>
<p>lmao</p>



<a name="190964255"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964255" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964255">(Mar 18 2020 at 10:54)</a>:</h4>
<p>yeah uhhh I've been planning to work on that for ages</p>



<a name="190964350"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964350" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964350">(Mar 18 2020 at 10:55)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> <span class="user-mention" data-user-id="133247">@bjorn3</span> <a href="https://github.com/rust-lang/rust/issues/46213" target="_blank" title="https://github.com/rust-lang/rust/issues/46213">https://github.com/rust-lang/rust/issues/46213</a></p>



<a name="190964412"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964412" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964412">(Mar 18 2020 at 10:56)</a>:</h4>
<p>I also have some notes somewhere on how to do it</p>



<a name="190964421"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964421" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964421">(Mar 18 2020 at 10:56)</a>:</h4>
<p>I think it requires a slight redesign of the enum layout code, which might slow it down</p>



<a name="190964456"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964456" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964456">(Mar 18 2020 at 10:56)</a>:</h4>
<p>but basically we first compute the unoptimized layout and we only pick an optimization if it's <em>smaller</em></p>



<a name="190964499"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964499" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964499">(Mar 18 2020 at 10:57)</a>:</h4>
<p>because tagged enums are always easier for LLVM to work with, IIRC, and this way we don't have to be clever about ensuring an optimized layout is smaller</p>



<a name="190964511"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964511" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964511">(Mar 18 2020 at 10:57)</a>:</h4>
<p>we just check</p>



<a name="190964661"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964661" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964661">(Mar 18 2020 at 10:59)</a>:</h4>
<p>so we can fix <a href="https://github.com/rust-lang/rust/issues/63866" target="_blank" title="https://github.com/rust-lang/rust/issues/63866">https://github.com/rust-lang/rust/issues/63866</a> that way then try to compute the layout for <a href="https://github.com/rust-lang/rust/issues/46213" target="_blank" title="https://github.com/rust-lang/rust/issues/46213">https://github.com/rust-lang/rust/issues/46213</a></p>



<a name="190964874"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964874" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964874">(Mar 18 2020 at 11:01)</a>:</h4>
<p>the best part is everything using layouts (miri, codegen) should work unchanged (barring any bugs) once we optimize layouts with non-empty niche variants</p>



<a name="190964943"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190964943" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190964943">(Mar 18 2020 at 11:01)</a>:</h4>
<p>the word "dataful" would be a lie at that point I guess</p>



<a name="190965020"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190965020" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190965020">(Mar 18 2020 at 11:02)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> <span class="user-mention" data-user-id="127617">@Shnatsel</span> <span class="user-mention" data-user-id="133247">@bjorn3</span> lol <a href="https://github.com/rust-lang/rust/issues/46213#issuecomment-394388912" target="_blank" title="https://github.com/rust-lang/rust/issues/46213#issuecomment-394388912">https://github.com/rust-lang/rust/issues/46213#issuecomment-394388912</a></p>



<a name="190966167"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/190966167" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#190966167">(Mar 18 2020 at 11:16)</a>:</h4>
<p><span class="user-mention silent" data-user-id="119009">eddyb</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Cow.20layout.20stability/near/190964874" title="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Cow.20layout.20stability/near/190964874">said</a>:</p>
<blockquote>
<p>the best part is everything using layouts (miri, codegen) should work unchanged (barring any bugs) once we optimize layouts with non-empty niche variants</p>
</blockquote>
<p>I hope so :) that will put my understanding of niches to the test though ;)</p>



<a name="192093254"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/192093254" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#192093254">(Mar 27 2020 at 23:41)</a>:</h4>
<p>oh look at that <a href="https://github.com/rust-lang/rust/pull/70477" title="https://github.com/rust-lang/rust/pull/70477">https://github.com/rust-lang/rust/pull/70477</a></p>



<a name="192093354"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/192093354" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#192093354">(Mar 27 2020 at 23:43)</a>:</h4>
<p>I probably would've forgotten about it for another year tbh</p>



<a name="192114194"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow%20layout%20stability/near/192114194" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Cow.20layout.20stability.html#192114194">(Mar 28 2020 at 09:20)</a>:</h4>
<p>I dont think I entirely understand what this does, but the wins in <code>static_assert_size</code> are nice :D</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>